home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1997 August / Walnut Creek CDROM.7z / LISTINGS / V_13_04 / CHAPMAN2 / CHAPMAN2.ZIP / TSTCOMPL.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-19  |  5.9 KB  |  177 lines

  1. /* tstcompl.cpp / test of complaint printer */
  2.  
  3. /* here's the scoop: we write a dummy complaint dictionary file, then go */
  4. /* out and read it to ensure that we can obtain values from it. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include "utils.hpp"                    /* skipblanks() etc. */
  9. #include "errmgr.hpp"                   /* ASSERT() */
  10. #include "c_failur.hpp"                 /* counting_failure_handler */
  11. #include "complain.hpp"                 /* what we're testing */
  12.  
  13. /* message "foo" is a test of the method used to get a backslash */
  14. /* (continuation character) at the end of a message. */
  15.  
  16. static const char *msgs1[] = {          /* table of good stuff */
  17.     "\n",                               /* blank line */
  18.     "# comment line\n",                 /* as it says */
  19.     "a: testing\n",                     /* single-line message */
  20.     "b:testing two\n",                  /* no space after colon */
  21.     "c : testing three\n",              /* space before colon */
  22.     "d: testing four\\\ntesting five\n",  /* two line message */
  23.     "e: testing six\\\ntesting seven\\\ntesting eight\n",  /* three lines */
  24.     "foo: backslash at end of line\\\\\n\n",  /* as it says */
  25.     "123: numeric message key\n",       /* keys are alphanumeric */
  26.     0
  27. };
  28.  
  29. static const char *msgnames1[] = {      /* names of what we expect to find */
  30.     "",                                 /* nothing for this line */
  31.     "",                                 /* ditto */
  32.     "a",                                /* first valid line */
  33.     "b",
  34.     "c",
  35.     "d",
  36.     "e",
  37.     "foo",
  38.     "123",
  39.     0
  40. };
  41.  
  42. static const char *msgs2[] = {          /* table full of errors */
  43.     "a: valid key\n",                   /* test for duplicate key */
  44.     "a: duplicate key\n",
  45.     "^&*^*&: non-alphanumeric key\n",
  46.     "abcdef missing ':'\n",
  47.     0
  48. };
  49.  
  50. static int write_complaint_file(const char *filename,
  51.                                 const char **text);
  52. static int compare_results(complaint_dict *dict,char *line,int linelen,
  53.                            const char *msgname,const char *testline);
  54. static int compare_strings(const char *dict_str,const char *test_str);
  55.  
  56.  
  57. int main(int argc,char *argv[])
  58. {
  59.     char line[512];
  60.     int i,all_ok = 1;
  61.     complaint_dict *dict;
  62.     char tempname[32];
  63.     counting_failure_handler count;     /* self-installing */
  64.  
  65.     /* write a file of keyed error messages */
  66.  
  67.     tmpnam(tempname);
  68.     if (write_complaint_file(tempname,msgs1))
  69.         return EXIT_FAILURE;
  70.  
  71.     /* now read them into a dictionary. */
  72.  
  73.     dict = new complaint_dict(tempname);
  74.  
  75.     /* next, ensure they got there properly. */
  76.  
  77.     for (i = 0; msgs1[i]; ++i)          /* compare each message */
  78.         if (!compare_results(dict,line,sizeof(line),msgnames1[i],msgs1[i]))
  79.             all_ok = 0;
  80.     delete dict;
  81.  
  82.     if (count.errors_logged() || count.warns_logged())
  83.         all_ok = 0;
  84.  
  85.     /* now test the error handling code. we can only count the number */
  86.     /* of warnings. there should be three. */
  87.  
  88.     remove(tempname);
  89.     if (write_complaint_file(tempname,msgs2))
  90.         return EXIT_FAILURE;
  91.     dict = new complaint_dict(tempname);
  92.     if (count.warns_logged() != 3L) {
  93.         err_mgr.warn("Invalid number of warnings: expected 3, got %ld\n",
  94.                      count.warns_logged());
  95.         all_ok = 0;
  96.     }
  97.  
  98.     delete dict;
  99.     remove(tempname);
  100.     if (all_ok)
  101.         fprintf(stdout,"all tests succeeded\n");
  102.     return all_ok ? EXIT_SUCCESS : EXIT_FAILURE;
  103.  
  104. }  /* end of main() */
  105.  
  106. static int write_complaint_file(const char *filename,
  107.                                 const char **msgs)
  108. {
  109.     /* write the text to the named file. return 1 on failure, 0 on success. */
  110.  
  111.     int i;
  112.     FILE *tempfile;
  113.  
  114.     if ((tempfile = fopen(filename,"w")) == NULL) {
  115.         fprintf(stderr,"Unable to create temporary file\n");
  116.         return 1;
  117.     }
  118.     for (i = 0; msgs[i]; ++i)
  119.         fputs(msgs[i],tempfile);
  120.     fclose(tempfile);
  121.     return 0;
  122.  
  123. }  /* end of write_complaint_file() */
  124.  
  125. static int compare_results(complaint_dict *dict,char *line,int linelen,
  126.                            const char *msgname,const char *testline)
  127. {
  128.     /* compare the text of testline with what's in the dictionary. skip */
  129.     /* the message name in the front (we use msgname for the lookup), then */
  130.     /* compare what's left with what comes back from the dictionary. ignore */
  131.     /* any backslash that is right before a newline in testline. */
  132.  
  133.     if (!*msgname)
  134.         return 1;                       /* assumed to be OK */
  135.     if (!dict->key_defined(msgname)) {
  136.         fprintf(stderr,"key_defined() failed for key %s\n",msgname);
  137.         return 0;
  138.     }
  139.     if (!dict->complaint_text(msgname,line,linelen)) {
  140.         fprintf(stderr,"lookup failed for key %s\n",msgname);
  141.         return 0;
  142.     }
  143.  
  144.     testline += skip_ident(testline);
  145.     testline += skipblanks(testline);
  146.     ASSERT(*testline == ':');
  147.     ++testline;
  148.     testline += skipblanks(testline);
  149.  
  150.     return compare_strings(line,testline) == 0;
  151.  
  152. }  /* end of compare_results() */
  153.  
  154. static int compare_strings(const char *dict_str,const char *test_str)
  155. {
  156.     /* compare the two strings, ignoring any backslash in test_str that's */
  157.     /* right in front of a newline (the dictionary will strip it out when */
  158.     /* it combines lines in the file). */
  159.  
  160.     /* returns negative, 0, or positive (just like strcmp()). */
  161.  
  162.     /* there's no good way to write this; the exit has to be in the */
  163.     /* middle of the loop, after skipping '\\' and before incrementing. */
  164.  
  165.     for (;;) {                          /* exit from within */
  166.         if (*test_str == '\\' && *(test_str + 1) == '\n')
  167.             ++test_str;
  168.         if (!*dict_str || !*test_str || *dict_str != *test_str)
  169.             return *dict_str - *test_str;
  170.         ++dict_str;
  171.         ++test_str;
  172.     }  /* end of for(ever) */
  173.  
  174.     /* NOTREACHED */
  175.  
  176. }  /* end of compare_strings() */
  177.